home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / comm / async.zip / MINT.C < prev    next >
C/C++ Source or Header  |  1986-10-23  |  7KB  |  329 lines

  1. #define LINT_ARGS
  2. #include <stdio.h>
  3.  
  4. #ifdef MSC
  5. #include <conio.h>
  6. #include <dos.h>
  7. #else
  8. #define inp(x) inportb(x)
  9. #define outp(x,y) outportb(x,y)
  10. #define int86(x,y,z) sysint(x,y,z)
  11. struct WORDREGS {
  12.     unsigned int ax;
  13.     unsigned int bx;
  14.     unsigned int cx;
  15.     unsigned int dx;
  16.     unsigned int si;
  17.     unsigned int di;
  18.     unsigned int ds;
  19.     unsigned int es;
  20.     };
  21. struct BYTEREGS {
  22.     unsigned char al, ah;
  23.     unsigned char bl, bh;
  24.     unsigned char cl, ch;
  25.     unsigned char dl, dh;
  26.     };
  27. union REGS {
  28.     struct WORDREGS x;
  29.     struct BYTEREGS h;
  30.     };
  31. #endif
  32.  
  33. #define COMBUFSIZE 2048
  34. #define OUTBUFSIZE 2048
  35. #define TIMEOUT EOF
  36. #define TICKSPERSEC    18
  37. char combuf[COMBUFSIZE];
  38. int inbufin = 0;
  39. int inbufout = 0;
  40. int inchrcnt = 0;
  41.  
  42. char outbuf[OUTBUFSIZE];
  43. int outchrcnt = 0;
  44. int outbufin = 0, 
  45. outbufout = 0;
  46.  
  47. #ifdef DEBUG
  48. print_status()
  49. {
  50.     fprintf(stderr,"\033[s\033[23;20H");
  51.     fprintf(stderr,"inbufin=%02d inbufout=%02d inchrcnt=%02d ",
  52.         inbufin,inbufout,inchrcnt);
  53.     fprintf(stderr,"outbufin=%02d outbufout=%02d outchrcnt=%02d ",
  54.         outbufin,outbufout,outchrcnt);
  55.     fprintf(stderr,"\033[u");
  56. }
  57. #endif
  58.  
  59. int comadr;
  60. int comport;
  61. int intnum, intmask, intreg;
  62.  
  63. #ifdef MSC
  64. unsigned peekw(offset,segment)
  65. unsigned offset,segment;
  66. {
  67.     union { unsigned far *ptr; struct { unsigned off, seg } parts } peeker;
  68.     peeker.parts.off = offset; peeker.parts.seg = segment;
  69.     return *(peeker.ptr);
  70. }
  71. #endif
  72.  
  73. outbuf_purge()
  74. {
  75.     cli();
  76.     outchrcnt = outbufin = outbufout = 0;
  77.     sti();
  78. }
  79.  
  80. inbuf_purge()
  81. {
  82.     cli();
  83.     inchrcnt = inbufin = inbufout = 0;
  84.     sti();
  85. }
  86.  
  87. async_status()
  88. {
  89.     return inchrcnt;
  90. }
  91.  
  92. /*
  93.  * timeout_read(timeout)
  94.  * waits for data from com port for timeout seconds
  95.  */
  96.  
  97. unsigned long clock()
  98. {
  99.     static union REGS regs;
  100.     regs.x.ax = 0;
  101.     int86(0x1A,®s,®s);
  102.     return ((long)regs.x.dx+((long)regs.x.cx << 16));
  103. }
  104.  
  105. long timerset(timeout)
  106. int timeout;
  107. {
  108.     return (clock() + ((timeout/10)*TICKSPERSEC));
  109. }
  110.  
  111. int timeup(timer)
  112. long timer;
  113. {
  114.     if (timer < clock())
  115.         return 1;
  116.     return 0;
  117. }
  118.  
  119. int carrier()
  120. {
  121.     /* carrier detect is the msb of the modem status register */
  122.     return (inp(comadr+6) & 0x80);
  123. }
  124.  
  125. unsigned timeout_read(timeout)
  126.     int timeout;
  127. {
  128.     unsigned long time;
  129.     unsigned char async_getc();
  130.     if (timeout == 0)    /* if they don't want to wait */
  131.         return (async_status() ? async_getc() : TIMEOUT);        
  132.     time = clock();
  133.     /* adjust from tenths (about 2 per clock tick) to clock ticks */
  134.     time += (long)(timeout << 1);
  135.     /* loop until timeout or char ready */
  136.     while (time > clock())
  137.     {
  138.         if (async_status())
  139.             return async_getc();
  140.     }
  141.     return (TIMEOUT);
  142. }
  143.  
  144. async_putc(c)
  145.     unsigned c;
  146. {
  147.  
  148.     /* if output buffer is full then poll till it is */
  149.     if (outchrcnt == OUTBUFSIZE)
  150.         while(outchrcnt == OUTBUFSIZE)
  151.             ;
  152.     outbuf[outbufin] = c;
  153.     if (++outbufin == OUTBUFSIZE)
  154.         outbufin = 0;
  155.     outchrcnt++;
  156.     /* enable data available, tx holding empty */
  157.     outp(comadr+1,0x3);
  158. }
  159.  
  160. unsigned char
  161. async_getc()
  162. {
  163.     register unsigned char c;
  164.     while(!async_status())
  165.         ;
  166.     c = combuf[inbufout++];
  167.     --inchrcnt;
  168.     if (inbufout == COMBUFSIZE)
  169.         inbufout = 0;
  170.     return c;
  171. }
  172.  
  173. #ifdef MSC
  174. /* #pragma check_stack- */
  175. #endif
  176.  
  177. void comserv()
  178. {
  179.     register unsigned c;
  180.     register unsigned int_reason;
  181.     outp(0x20,0x20);    /* signal non-specific EOI */
  182.  
  183.     /* check for character read */
  184.     if (4 == (int_reason = inp(comadr+2)))
  185.     {
  186.         /* check line status for data ready */
  187.         if ( inp(comadr+5) & 0x1 )
  188.         {
  189. rcvdata:
  190.             c = inp(comadr);
  191.             combuf[inbufin++] = c;
  192.             if (inbufin == COMBUFSIZE)
  193.                 inbufin = 0;
  194.             ++inchrcnt;
  195.         }
  196.         /* if the transmit holding buffer isn't empty, return */
  197.         if ( inp(comadr+5) & 0x20 )
  198.             goto snddata;
  199.         else
  200.             return;
  201.     } 
  202.  
  203.     /* check for character write */
  204.     if (2 == int_reason)
  205.     {
  206.         if ( inp(comadr+5) & 0x20 )
  207.         {
  208. snddata:
  209.             if (outchrcnt)
  210.             {
  211.                 outp(comadr,outbuf[outbufout]);
  212.                 if (++outbufout == OUTBUFSIZE)
  213.                     outbufout = 0;
  214.                 if (!--outchrcnt)
  215.                     /* disable tx holding empty interrupt */
  216.                     outp(comadr+1,0x1);
  217.             }
  218.         }
  219.         /* check for data ready */
  220.         if ( inp(comadr+5) & 0x1 ) 
  221.             goto rcvdata;
  222.         else
  223.             return;
  224.     }
  225. }
  226.  
  227. #ifdef MSC
  228. /* #pragma check_stack+ */
  229. #endif
  230.  
  231. async_port_setup(com,baud,parity,wordwidth,stopbits)
  232. {
  233.     union REGS regs;
  234.     register setup_mask;
  235.     register port_mask;
  236.     switch(com)
  237.     {
  238.     case 0: comport = 0; break;
  239.     case 1: comport = 1; break;
  240.     default: return -1;
  241.     }
  242.     switch(baud)
  243.     {
  244.     case 110: setup_mask = 0; break;
  245.     case 300: setup_mask = 0x40; break;
  246.     case 600: setup_mask = 0x60; break;
  247.     case 1200: setup_mask = 0x80; break;
  248.     case 2400: setup_mask = 0xA0; break;
  249.     case 4800: setup_mask = 0xC0; break;
  250.     case 9600: setup_mask = 0xE0; break;
  251.     default: return -1;
  252.     }
  253.     switch (parity)
  254.     {
  255.     case 0: break;
  256.     case 1: setup_mask |= 0x8; break; 
  257.     case 2: setup_mask |= 0xA; break;
  258.     default: return -1;
  259.     }
  260.     switch (stopbits)
  261.     {
  262.     case 1: break;
  263.     case 2: setup_mask |= 0x4; break;
  264.     default: return -1;
  265.     }
  266.     switch (wordwidth)
  267.     {
  268.     case 7: setup_mask |= 0x2; break;
  269.     case 8: setup_mask |= 0x3; break;
  270.     default: return -1;
  271.     }
  272.     /* call rom bios to set port parms */ 
  273.     regs.x.ax = setup_mask & 0xFF;
  274.     regs.x.dx = comport;
  275.     int86(0x14,®s,®s);
  276.     return 0;
  277. }
  278.  
  279. async_init(com)
  280. {
  281.     register setup_mask;
  282.     register port_mask;
  283.  
  284.     switch(com)
  285.     {
  286.     case 0: comport = 0; intnum = 0xC; intmask = 0xEF; break;
  287.     case 1: comport = 1; intnum = 0xB; intmask = 0xF7; break;
  288.     default: return -1;
  289.     }
  290.     /* purge the buffers */
  291.     inbuf_purge(); outbuf_purge();
  292.     /* set up the communications interrupt */
  293.     setup_comint(intnum);
  294.     
  295.     /* get comport base address out of rom bios data segment */
  296.     comadr = peekw(comport << 1,0x40);
  297.     
  298.     /* get int enable port mask */
  299.     intreg = inp(comadr+1);
  300.  
  301.     /* enable data available */
  302.     outp(comadr+1,intreg | 0x1);
  303.  
  304.     /* turn on OUT2 */
  305.     outp(comadr+4,0xB);
  306.  
  307.     inp(comadr); inp(comadr); /* two dummy reads to clear status */
  308.  
  309.     port_mask = inp(0x21);            /* get int controller mask */
  310.     outp(0x21,port_mask & intmask);    /* turn on interrupts from com port */
  311.     outp(0x20,0x20);                /* signal EOI */
  312.     return 0;
  313. }
  314.  
  315. async_restore()
  316. {
  317.     register int port_mask;
  318.     /* disable com port interrupts */
  319.     outp(comadr+1,intreg);
  320.  
  321.     /* get currently masked interrupts */
  322.     port_mask = inp(0x21);
  323.     /* set the appropriate bit for current com port */
  324.     outp(0x21, (port_mask | (intmask ^ 0xFF)));
  325.  
  326.     /* restore interrupt handler */
  327.     restore_comint(intnum);
  328. }
  329.